package org.dromara.xxmj.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Maps;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.xxmj.domain.*;
import org.dromara.xxmj.domain.dto.ExerciseSubmitDto;
import org.dromara.xxmj.domain.dto.GetQuestionListDTO;
import org.dromara.xxmj.domain.dto.SimulationSubmitDTO;
import org.dromara.xxmj.domain.vo.*;
import org.dromara.xxmj.mapper.*;
import org.dromara.xxmj.domain.po.UserCollectQuestionInfo;
import org.dromara.xxmj.domain.po.UserErrorQuestionInfo;
import org.dromara.xxmj.service.XxmjExercisesService;
import org.dromara.xxmj.utils.CheckUtils;
import org.dromara.xxmj.utils.ConvertUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;

/**
 * 小巷密卷用户扩展Service业务层处理
 *
 * @author Lion Li
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class XxmjExercisesServiceImpl implements XxmjExercisesService {

    @Resource
    private CourseQuestionMapper courseQuestionMapper; //刷题题库

    @Resource
    private CourseExerciseMapper courseExerciseMapper;//课后习题题库

    @Resource
    private CourseSimulationMapper courseSimulationMapper;//模拟题库

    @Resource
    private UserErrorQuestionInfoMapper userErrorQuestionInfoMapper;

    @Resource
    private UserCollectQuestionInfoMapper userCollectQuestionInfoMapper;

    @Resource
    private UserExerciseRecordMapper userExerciseRecordMapper;

    @Resource
    private CourseScoreMapper courseScoreMapper;

    @Resource
    private CourseExerciseMapper courseExeMapper;

    @Resource
    private ConvertUtils convertUtils;

    @Resource
    private CheckUtils checkUtils;

    @Override
    public List<CourseGeneralVO> list(GetQuestionListDTO getQuestionListDTO) {
        log.info("课程类型：{}", getQuestionListDTO.getCourseType());
        Integer courseType = getQuestionListDTO.getCourseType();
        Integer courseId = getQuestionListDTO.getCourseId();//课程ID
        Long userId = Convert.toLong(LoginHelper.getUserId(), 1L);

        List<CourseGeneralVO> list = new ArrayList<>();
        switch (courseType) {
            case 1 -> {
                List<CourseExerciseVo> exerciseList = courseExerciseMapper.selectExercisesByVideoId(Convert.toLong(courseId),Convert.toLong(getQuestionListDTO.getVideoId()),userId);
                convertUtils.convertAndAddToList(exerciseList, CourseExerciseVo.class, list);
            }
            case 2 -> {
                List<CourseQuestionVO> questionList = courseQuestionMapper.selectQuestionsByCourseId(Convert.toLong(courseId), userId);
                convertUtils.convertAndAddToList(questionList, CourseQuestionVO.class, list);
            }
            case 3 -> {
                if (getQuestionListDTO.getSimulationId() == null){
                    throw new ServiceException("未选择试卷，请重新选择!");
                }
                List<CourseSimulationVO> simulationList = courseSimulationMapper.selectSimulationByVideoAndSimulationId(courseId,getQuestionListDTO.getSimulationId(),userId);
                convertUtils.convertAndAddToList(simulationList, CourseSimulationVO.class, list);
            }
            case 4 ->{
                List<UserErrorQuestionInfoVO> errorQustionList = userErrorQuestionInfoMapper.getDetailList(userId);
                convertUtils.convertAndAddToList(errorQustionList, UserErrorQuestionInfoVO.class, list);
            }
            case 5 ->{
                List<UserCollectQuestionInfoVO> collectQuestionList = userCollectQuestionInfoMapper.selectVoList(Wrappers.<UserCollectQuestionInfo>lambdaQuery()
                    .eq(UserCollectQuestionInfo::getStuId, userId));
                convertUtils.convertAndAddToList(collectQuestionList, UserCollectQuestionInfoVO.class, list);
            }
            default -> throw new ServiceException("未知的课程类型");
        }
        return list;
    }

    @Override
    public List<UserErrorQuestionInfoVO> getDetailList(Long stuId) {
        return userErrorQuestionInfoMapper.getDetailList(stuId);
    }

    @Override
    public List<UserCollectQuestionInfoVO> getCollectList(String stuId) {
        return userCollectQuestionInfoMapper.selectVoList(Wrappers.<UserCollectQuestionInfo>lambdaQuery()
            .eq(UserCollectQuestionInfo::getStuId, stuId));
    }

    @Override
    public void delete(Long id) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser != null) {
            checkUtils.checkAdmin(loginUser);
        }
        Long userId = null;
        if (loginUser != null) {
            userId = loginUser.getUserId();
        }
        userErrorQuestionInfoMapper.delete(Wrappers.<UserErrorQuestionInfo>lambdaQuery()
            .eq(UserErrorQuestionInfo::getStuId, userId)
            .eq(UserErrorQuestionInfo::getId, id));
    }

    @Override
    public void detailSubmitAnswer(ExerciseSubmitDto dto) {
        Long userId = Convert.toLong(LoginHelper.getUserId(), 123456L);
        Long exerciseId = dto.getExerciseId();
        Integer courseType = dto.getCourseType();
        CourseGeneralVO generalVO = new CourseGeneralVO();

        LambdaQueryWrapper<UserErrorQuestionInfo> queryWrapper = Wrappers.<UserErrorQuestionInfo>lambdaQuery()
            .eq(UserErrorQuestionInfo::getStuId, userId).eq(UserErrorQuestionInfo::getQuestionId, dto.getExerciseId());
        UserErrorQuestionInfo userErrorQuestionInfo = userErrorQuestionInfoMapper.selectOne(queryWrapper);

        if (userErrorQuestionInfo == null){
            throw new ServiceException("用户错题库不存在此题");
        }

        BeanUtil.copyProperties(userErrorQuestionInfo, generalVO,"id");

        // 判断答案是否正确
        boolean isCorrect = checkUtils.checkAnswer(generalVO, dto.getUserAnswer());
        dto.setIsCorrect(isCorrect ? "1" : "0");

        // 保存用户答题记录
        LambdaQueryWrapper<UserExerciseRecord> exerciseQueryWrapper = Wrappers.lambdaQuery();
        exerciseQueryWrapper.eq(UserExerciseRecord::getUserId, userId).eq(UserExerciseRecord::getQuestionType, courseType)
            .eq(UserExerciseRecord::getExerciseId, exerciseId);

        //更新记录
        UserExerciseRecord record = userExerciseRecordMapper.selectOne(exerciseQueryWrapper);
        if (record != null) {
            // 更新记录
            record.setUserAnswer(dto.getUserAnswer());
            record.setQuestionType(courseType);
            record.setIsCorrect(dto.getIsCorrect());
            record.setUpdateTime(new Date());
            userExerciseRecordMapper.updateById(record);
        } else {
            // 新增记录
            record = new UserExerciseRecord();
            record.setUserId(userId);
            record.setExerciseId(exerciseId);
            record.setCourseId(generalVO.getCourseId());
            record.setUserAnswer(dto.getUserAnswer());
            record.setIsCorrect(dto.getIsCorrect());
            record.setQuestionType(courseType);
            record.setCreateTime(new Date());
            record.setUpdateTime(new Date());
            userExerciseRecordMapper.insert(record);
        }

        //如果正确，移除错题库
        if (isCorrect) {
            userErrorQuestionInfoMapper.delete(Wrappers.<UserErrorQuestionInfo>lambdaQuery()
                .eq(UserErrorQuestionInfo::getStuId, userId)
                .eq(UserErrorQuestionInfo::getQuestionId, exerciseId));
        }
    }

    @Override
    public SubmitSimulationVO submitSimulation(SimulationSubmitDTO dto) {
        Long userId = LoginHelper.getUserId(); //学生ID
        List<ExerciseSubmitDto> answerInfo = dto.getAnswerInfo();
        double totalScore = 0;
        LambdaQueryWrapper<CourseSimulation> courseSimulationWrapper = new LambdaQueryWrapper<>();
        courseSimulationWrapper.eq(CourseSimulation::getCourseId,dto.getCourseId()).eq(CourseSimulation::getSimulationId,dto.getSimulationId());
        Long questionCount = courseSimulationMapper.selectCount(courseSimulationWrapper);
//        int correctNumber;
        Integer errorNumber = 0;

        List<UserExerciseRecord> insertExerciseList = new ArrayList<>();
        List<UserExerciseRecord> updateExerciseList = new ArrayList<>();
        List<UserErrorQuestionInfo> insertErrorList = new ArrayList<>();

        for (ExerciseSubmitDto dto1 : answerInfo) {
            long exerciseId = dto1.getExerciseId();
            String userAnswer = Convert.toStr(dto1.getUserAnswer(),"");

            CourseGeneralVO  generalVO = new CourseGeneralVO();
            generalVO.setSimulationId(dto.getSimulationId());
            generalVO.setCourseId(dto.getCourseId());
            generalVO.setType(Convert.toStr(dto1.getCourseType()));
            generalVO.setUserAnswer(userAnswer);
            generalVO.setId(exerciseId);

            BeanUtil.copyProperties(generalVO, dto1,"id");
            Integer courseType = dto1.getCourseType();

            int isCorrect = 0;
            if (StrUtil.isNotBlank(userAnswer)){
                LambdaQueryWrapper<CourseSimulation> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(CourseSimulation::getId, generalVO.getId()).eq(CourseSimulation::getCourseId, generalVO.getCourseId())
                    .eq(CourseSimulation::getSimulationId,generalVO.getSimulationId());
                CourseSimulationVO courseSimulationVO = courseSimulationMapper.selectVoOne(queryWrapper);
                if (courseSimulationVO == null){
                    throw new IllegalArgumentException("未找到此试题，请联系管理员处理！");
                }

                Double score = courseSimulationVO.getScore();
                String correctAnswer = courseSimulationVO.getAnswer();
                String type = courseSimulationVO.getType();
                if ("0".equals(type) || "2".equals(type)) {
                    // 单选题或判断题，直接比较
                    if (correctAnswer.equals(userAnswer)) {
                        totalScore += score;
                        isCorrect = 1;
                    }
                } else if ("1".equals(type)) {
                    // 多选题，需要排序后比较
                    String answer = courseSimulationVO.getAnswer(); // 正确答案
                    String[] answers = answer.split(","); // 拆分为单个答案数组
                    // 获取题目总分
                    // 计算每项答案对应的分数
                    double oneScore = Convert.toDouble(score, 0.0) / answers.length;
                    oneScore = Math.round(oneScore * 100) / 100.0; // 保留两位小数

                    for (String correct : answers) {
                        if (userAnswer.contains(correct)) {
                            totalScore += oneScore; // 如果用户答案匹配正确答案项，则加分
                        }
                    }

                    String[] correctParts = correctAnswer.split(",");
                    String[] userParts = userAnswer.split(",");
                    // 排序后比较（适用于多选题）
                    Arrays.sort(correctParts);
                    Arrays.sort(userParts);

                    if (Arrays.equals(correctParts, userParts)) {
                        isCorrect = 1;
                    }
                } else if ("3".equals(type)) {
                    String answer = courseSimulationVO.getAnswer(); //正确回答
                    String answerStr = answer.toLowerCase(); //小写

                    String[] answers = StringUtils.split(answer, ",");
                    double oneScore = Convert.toDouble(score, 0.0) / answers.length;
                    oneScore = Math.round(oneScore * 100) / 100.0;
                    for (String oneAnswer : answers) {
                        if (answerStr.contains(oneAnswer.toLowerCase())) {
                            totalScore += oneScore;
                        }
                    }
                    if (correctAnswer.equals(userAnswer)) {
                        totalScore += score;
                        isCorrect = 1;
                    }
                }
            }
            dto1.setIsCorrect(Convert.toStr(isCorrect,"0"));

            // 保存用户答题记录
            LambdaQueryWrapper<UserExerciseRecord> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(UserExerciseRecord::getUserId, userId).eq(UserExerciseRecord::getQuestionType, courseType)
                .eq(UserExerciseRecord::getExerciseId, exerciseId).eq(UserExerciseRecord::getCourseId,dto.getCourseId());

            UserExerciseRecord record = userExerciseRecordMapper.selectOne(queryWrapper);
            if (record != null) {
                // 更新记录
                record.setUserAnswer(userAnswer);
                record.setCourseId(generalVO.getCourseId());
                record.setQuestionType(courseType);
                record.setIsCorrect(dto1.getIsCorrect());
                updateExerciseList.add(record);
            } else {
                // 新增记录
                record = new UserExerciseRecord();
                record.setUserId(userId);
                record.setExerciseId(exerciseId);
                record.setCourseId(dto.getCourseId());//课程ID
                record.setUserAnswer(userAnswer);
                record.setQuestionType(courseType); //类型
                record.setIsCorrect(dto1.getIsCorrect());
                insertExerciseList.add(record);
            }

            //错题库
            if (dto1.getIsCorrect().equals("0")) {
                // 查询是否已存在该错题记录
                LambdaQueryWrapper<UserErrorQuestionInfo> errorQuestionWrapper = Wrappers.<UserErrorQuestionInfo>lambdaQuery()
                    .eq(UserErrorQuestionInfo::getStuId, userId).eq(UserErrorQuestionInfo::getQuestionId, exerciseId)
                    .eq(UserErrorQuestionInfo::getCourseId, dto.getCourseId());

                UserErrorQuestionInfo existingRecord = userErrorQuestionInfoMapper.selectOne(errorQuestionWrapper);
                //如果没有此错题，则加入错题本
                if (existingRecord == null) {
                    courseSimulationWrapper.eq(CourseSimulation::getId,dto1.getExerciseId());
                    CourseSimulation courseSimulation = courseSimulationMapper.selectOne(courseSimulationWrapper);

                    UserErrorQuestionInfo userErrorQuestionInfo = new UserErrorQuestionInfo();
                    BeanUtil.copyProperties(generalVO, userErrorQuestionInfo,"id");
                    BeanUtil.copyProperties(courseSimulation, userErrorQuestionInfo,"id");

                    userErrorQuestionInfo.setStuId(Convert.toStr(userId)); //学生ID
                    userErrorQuestionInfo.setQuestionId(exerciseId); //习题ID
                    userErrorQuestionInfo.setType(generalVO.getType());
                    userErrorQuestionInfo.setQuestionType(3);
                    userErrorQuestionInfo.setSaveTime(new Date());
                    insertErrorList.add(userErrorQuestionInfo);
                }
                //加上错题数
                errorNumber ++;
            }
        }

        //如果记录数组新增不为空，批量插入
        if (CollUtil.isNotEmpty(insertExerciseList)){
            userExerciseRecordMapper.insert(insertExerciseList);
        }

        //如果记录数组更改不为空，批量更改
        if (CollUtil.isNotEmpty(insertExerciseList)){
            userExerciseRecordMapper.updateById(updateExerciseList);
        }

        //如果错题数组新增不为空，批量插入
        if (CollUtil.isNotEmpty(insertExerciseList)){
            userErrorQuestionInfoMapper.insert(insertErrorList);
        }

        int correctNumber = Convert.toInt(questionCount) - errorNumber; //正确数
        Double correctRate = Convert.toDouble(NumberUtil.div(Convert.toDouble(correctNumber), questionCount, 2)) * 100;
        totalScore = new BigDecimal(totalScore).setScale(1, RoundingMode.FLOOR).doubleValue();

        CourseScore courseScore = new CourseScore();
        courseScore.setStuId(Convert.toLong(Convert.toStr(userId)));
        courseScore.setCourseId(Convert.toLong(Convert.toInt(dto.getCourseId())));
        courseScore.setSimulationId(Convert.toLong(Convert.toInt(dto.getCourseId())));
        courseScore.setScore(totalScore);
        courseScore.setExamSpentTime(dto.getExamSpentTime());
        courseScore.setCreateTime(new Date());

        try {
            courseScoreMapper.insert(courseScore);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("新增用户考试分数库 courseScoreMapper.insert .Error");
        }

        SubmitSimulationVO resultVo = new SubmitSimulationVO();
        resultVo.setCorrectNumber(correctNumber);
        resultVo.setErrorNumber(errorNumber);
        resultVo.setCorrectRate(correctRate);
        resultVo.setTotalScore(totalScore);
        return resultVo;

    }

    @Override
    public List<CourseScore> getScoreList() {
        Long userId = LoginHelper.getUserId();
        LambdaQueryWrapper<CourseScore> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CourseScore::getStuId, userId);
        return courseScoreMapper.selectList(queryWrapper);
    }

    @Override
    public GetTodayPracticeVO getTodayPractice() {
        Long userId = LoginHelper.getUserId();
        GetTodayPracticeVO todayPractice = courseExeMapper.getTodayPractice(userId);
        List<Map<String,Object>> createDays = courseExeMapper.getCreateDays(userId);

        // 计算连续答题天数
        int consecutiveDays = calculateConsecutiveDays(createDays);

        // 设置连续答题天数
        if (todayPractice != null) {
            todayPractice.setConsecutiveDays(consecutiveDays);
        } else {
            // 如果今天没有练习记录，创建一个默认对象
            todayPractice = new GetTodayPracticeVO();
            todayPractice.setCourseName("暂无练习记录");
            todayPractice.setQuestionCount(0);
            todayPractice.setCorrectRate(0.0);
            todayPractice.setConsecutiveDays(consecutiveDays);
        }

        return todayPractice;
    }

    @Override
    public List<CoursePracticeVO> getRecentPractice() {
        Long userId = LoginHelper.getUserId();
        return courseExeMapper.getRecentPractice(userId);
    }

    /**
     * 计算连续答题天数
     * @param createDays 答题日期列表
     * @return 连续答题天数
     */
    private int calculateConsecutiveDays(List<Map<String, Object>> createDays) {
        if (createDays == null || createDays.isEmpty()) {
            return 0;
        }

        LocalDate today = LocalDate.now();
        int consecutiveDays = 0;

        // 将答题日期转换为LocalDate列表
        List<LocalDate> practiceDates = new ArrayList<>();
        for (Map<String, Object> dateMap : createDays) {
            Object createDate = dateMap.get("create_date");
            if (createDate != null) {
                LocalDate practiceDate;
                if (createDate instanceof java.sql.Date) {
                    practiceDate = ((java.sql.Date) createDate).toLocalDate();
                } else if (createDate instanceof Date) {
                    practiceDate = ((Date) createDate).toInstant()
                        .atZone(java.time.ZoneId.systemDefault())
                        .toLocalDate();
                } else {
                    // 尝试字符串解析
                    practiceDate = LocalDate.parse(createDate.toString());
                }
                practiceDates.add(practiceDate);
            }
        }

        // 从今天开始，向前检查连续答题天数
        LocalDate checkDate = today;
        while (practiceDates.contains(checkDate)) {
            consecutiveDays++;
            checkDate = checkDate.minusDays(1);
        }

        return consecutiveDays;
    }

    @Override
    public void addCollect(String courseId, Long questionId, Integer questionType) {
        String stuId = Convert.toStr(LoginHelper.getUserId());
        if (StrUtil.isBlank(stuId)){
            throw new ServiceException("未获取用户ID，请联系管理员处理！");
        }
        CourseGeneralVO generalVO = new CourseGeneralVO();
        switch (questionType) {
            case 1 -> {
                // 获取习题
                CourseExercise exercise = courseExerciseMapper.selectById(questionId);
                BeanUtil.copyProperties(exercise, generalVO,"id");
            }
            case 2 -> {
                CourseQuestionVO question = courseQuestionMapper.selectVoById(questionId);
                BeanUtil.copyProperties(question, generalVO,"id");
            }
            case 3 -> {
                CourseSimulationVO simulation = courseSimulationMapper.selectVoById(questionId);
                BeanUtil.copyProperties(simulation, generalVO,"id");
            }
            default -> throw new ServiceException("未知的题目类型");
        }

        UserCollectQuestionInfo collectQuestionInfo = new UserCollectQuestionInfo();
        BeanUtil.copyProperties(generalVO, collectQuestionInfo,"id");
        collectQuestionInfo.setStuId(stuId);
        collectQuestionInfo.setCourseId(Convert.toLong(courseId));
        collectQuestionInfo.setQuestionId(questionId);
        collectQuestionInfo.setSaveTime(new Date());
        collectQuestionInfo.setQuestionType(questionType);

        try {
            userCollectQuestionInfoMapper.insert(collectQuestionInfo);
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("新增用户收藏 collectQuestionInfoMapper.insert .Error");
        }

    }

    @Override
    public void cancelCollect(Long id) {
        Long userId = LoginHelper.getUserId();
        userCollectQuestionInfoMapper.delete(Wrappers.<UserCollectQuestionInfo>lambdaQuery()
            .eq(UserCollectQuestionInfo::getStuId, userId)
            .eq(UserCollectQuestionInfo::getId, id));
    }


}





